/*
This file is part of Arcadeflex.

Arcadeflex is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Arcadeflex is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Arcadeflex.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 *
 * rewrote for 0.28
 *
 *  games uses v0.36 romset
 *  
 */


package drivers;
import static arcadeflex.libc.*;
import static mame.commonH.*;
import static mame.cpuintrf.*;
import static mame.driverH.*;
import static mame.mame.*;
import static mame.osdependH.*;
import static sndhrdw.pengo.*;
import static vidhrdw.generic.*;
import static vidhrdw.xevious.*;
import static machine.xevious.*;

public class xevious {
    
        static MemoryReadAddress readmem_cpu1[] =
        {
                new MemoryReadAddress( 0x6800, 0x6807, xevious_dsw_r ),
                new MemoryReadAddress( 0x7000, 0x700f, xevious_customio_data_r ),
                new MemoryReadAddress( 0x7100, 0x7100, xevious_customio_r ),
                new MemoryReadAddress( 0x7800, 0xcfff, xevious_sharedram_r ),
                new MemoryReadAddress( 0xf000, 0xffff, xevious_bb_r ),
                new MemoryReadAddress( 0x0000, 0x3fff, MRA_ROM ),
                new MemoryReadAddress( -1 )	/* end of table */
        };

        static MemoryReadAddress readmem_cpu2[] =
        {
                new MemoryReadAddress( 0x6800, 0x6807, xevious_dsw_r ),
                new MemoryReadAddress( 0x7800, 0xcfff, xevious_sharedram_r ),
                new MemoryReadAddress( 0xf000, 0xffff, xevious_bb_r ),
                new MemoryReadAddress( 0x0000, 0x1fff, MRA_ROM ),
                new MemoryReadAddress( -1 )	/* end of table */
        };

        static MemoryReadAddress readmem_cpu3[] =
        {
                new MemoryReadAddress( 0x7800, 0xcfff, xevious_sharedram_r ),
                new MemoryReadAddress( 0x0000, 0x0fff, MRA_ROM ),
                new MemoryReadAddress( -1 )	/* end of table */
        };

        static MemoryWriteAddress writemem_cpu1[] =
        {
                new MemoryWriteAddress( 0x6820, 0x6820, xevious_interrupt_enable_1_w ),
                new MemoryWriteAddress( 0x6821, 0x6821, xevious_interrupt_enable_2_w ),
                new MemoryWriteAddress( 0x6822, 0x6822, xevious_interrupt_enable_3_w ),
                new MemoryWriteAddress( 0x6823, 0x6823, xevious_halt_w ),			/* reset controll */
                new MemoryWriteAddress( 0x6830, 0x683f, MWA_NOP ),				/* watch dock reset */
                new MemoryWriteAddress( 0x7000, 0x700f, xevious_customio_data_w ),
                new MemoryWriteAddress( 0x7100, 0x7100, xevious_customio_w ),
                new MemoryWriteAddress( 0x7800, 0xafff, xevious_sharedram_w, xevious_sharedram ),
                new MemoryWriteAddress( 0xb000, 0xb7ff, colorram_w, colorram ),
                new MemoryWriteAddress( 0xb800, 0xbfff, xevious_colorram2_w, xevious_colorram2 ),
                new MemoryWriteAddress( 0xc000, 0xc7ff, videoram_w, videoram, videoram_size ),
                new MemoryWriteAddress( 0xc800, 0xcfff, xevious_videoram2_w, xevious_videoram2 ),
                new MemoryWriteAddress( 0xd000, 0xd07f, xevious_vh_latch_w, xevious_vlatches ), /* ?? */
                new MemoryWriteAddress( 0xf000, 0xffff, xevious_bs_w ),
                new MemoryWriteAddress( 0x0000, 0x3fff, MWA_ROM ),
                new MemoryWriteAddress( 0x8780, 0x87ff, MWA_RAM, spriteram_2 ),	/* here only */
                new MemoryWriteAddress( 0x9780, 0x97ff, MWA_RAM, spriteram_3 ),	/* to initialize */
                new MemoryWriteAddress( 0xa780, 0xa7ff, MWA_RAM, spriteram, spriteram_size ),	/* the pointers */
                new MemoryWriteAddress( -1 )	/* end of table */
        };

        static MemoryWriteAddress writemem_cpu2[] =
        {
                new MemoryWriteAddress( 0x6820, 0x6820, xevious_interrupt_enable_1_w ),
                new MemoryWriteAddress( 0x6821, 0x6821, xevious_interrupt_enable_2_w ),
                new MemoryWriteAddress( 0x6822, 0x6822, xevious_interrupt_enable_3_w ),
                new MemoryWriteAddress( 0x6823, 0x6823, xevious_halt_w ),			/* reset controll */
                new MemoryWriteAddress( 0x6830, 0x683f, MWA_NOP ),				/* watch dock reset */
                new MemoryWriteAddress( 0x7800, 0xafff, xevious_sharedram_w ),
                new MemoryWriteAddress( 0xb000, 0xb7ff, colorram_w ),
                new MemoryWriteAddress( 0xb800, 0xbfff, xevious_colorram2_w ),
                new MemoryWriteAddress( 0xc000, 0xc7ff, videoram_w ),
                new MemoryWriteAddress( 0xc800, 0xcfff, xevious_videoram2_w ),
                new MemoryWriteAddress( 0xd000, 0xd07f, xevious_vh_latch_w ), /* ?? */
                new MemoryWriteAddress( 0xf000, 0xffff, xevious_bs_w ),
                new MemoryWriteAddress( 0x0000, 0x1fff, MWA_ROM ),
                new MemoryWriteAddress( -1 )	/* end of table */
        };

        static MemoryWriteAddress writemem_cpu3[] =
        {
                new MemoryWriteAddress( 0x7800, 0xcfff, xevious_sharedram_w ),
                new MemoryWriteAddress( 0x6800, 0x681f, pengo_sound_w, pengo_soundregs ),
                new MemoryWriteAddress( 0x6822, 0x6822, xevious_interrupt_enable_3_w ),
                new MemoryWriteAddress( 0x0000, 0x0fff, MWA_ROM ),
                new MemoryWriteAddress( -1 )	/* end of table */
        };
 
        
        static InputPortPtr xevious_input_ports= new InputPortPtr(){ public void handler() 
        {
                PORT_START();	/* DSW0 */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 );
                PORT_DIPNAME( 0x02, 0x02, "Unknown 1", IP_KEY_NONE );
                PORT_DIPSETTING(    0x02, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                PORT_DIPNAME( 0x0c, 0x0c, "Right Coin", IP_KEY_NONE );
                PORT_DIPSETTING(    0x0c, "1 Coin/1 Credit" );
                PORT_DIPSETTING(    0x08, "1 Coin/2 Credit" );
                PORT_DIPSETTING(    0x04, "1 Coin/3 Credits" );
                PORT_DIPSETTING(    0x00, "1 Coin/6 Credits" );
                PORT_DIPNAME( 0x10, 0x10, "Unknown 2", IP_KEY_NONE );
                PORT_DIPSETTING(    0x10, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                PORT_DIPNAME( 0x60, 0x60, "Difficulty", IP_KEY_NONE );
                PORT_DIPSETTING(    0x40, "Easy" );
                PORT_DIPSETTING(    0x60, "Normal" );
                PORT_DIPSETTING(    0x20, "Hard" );
                PORT_DIPSETTING(    0x00, "Hardest" );
                /* when switch is on Namco, high score names are 10 letters long */
                PORT_DIPNAME( 0x80, 0x80, "Copyright", IP_KEY_NONE );
                PORT_DIPSETTING(    0x00, "Namco" );
                PORT_DIPSETTING(    0x80, "Atari/Namco" );

                PORT_START();	/* DSW1 */
                PORT_DIPNAME( 0x03, 0x03, "Left Coin", IP_KEY_NONE );
                PORT_DIPSETTING(    0x01, "2 Coins/1 Credit" );
                PORT_DIPSETTING(    0x03, "1 Coin/1 Credit" );
                PORT_DIPSETTING(    0x00, "2 Coins/3 Credits" );
                PORT_DIPSETTING(    0x02, "1 Coin/2 Credits" );
                /* TODO: bonus scores are different for 5 lives */
                PORT_DIPNAME( 0x1c, 0x1c, "Bonus Life", IP_KEY_NONE );
                PORT_DIPSETTING(    0x18, "10000 40000" );
                PORT_DIPSETTING(    0x14, "10000 50000" );
                PORT_DIPSETTING(    0x10, "20000 50000" );
                PORT_DIPSETTING(    0x0c, "20000 70000" );
                PORT_DIPSETTING(    0x08, "20000 80000" );
                PORT_DIPSETTING(    0x1c, "20000 60000" );
                PORT_DIPSETTING(    0x04, "20000 and 60000" );
                PORT_DIPSETTING(    0x00, "None" );
                PORT_DIPNAME( 0x60, 0x60, "Lives", IP_KEY_NONE );
                PORT_DIPSETTING(    0x40, "1" );
                PORT_DIPSETTING(    0x20, "2" );
                PORT_DIPSETTING(    0x60, "3" );
                PORT_DIPSETTING(    0x00, "5" );
                PORT_DIPNAME( 0x80, 0x80, "Cabinet", IP_KEY_NONE );
                PORT_DIPSETTING(    0x80, "Upright" );
                PORT_DIPSETTING(    0x00, "Cocktail" );

                PORT_START();	/* FAKE */
                /* The player inputs are not memory mapped, they are handled by an I/O chip. */
                /* These fake input ports are read by galaga_customio_data_r() */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY );
                PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY );
                PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY );
                PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY );
                PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED );	/* there's a BUTTON1 | IMPULSE here, */
                                                                                                        /* handled by galaga_customio_data_r() */
                PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 );
                PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED );

                PORT_START();	/* FAKE */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED );	/* there's a BUTTON1 | IMPULSE here, */
                                                                                                        /* handled by galaga_customio_data_r() */
                PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL );
                PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED );

                PORT_START();	/* FAKE */
                PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNUSED );
                PORT_BITX(0x04, IP_ACTIVE_LOW, IPT_START1 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x08, IP_ACTIVE_LOW, IPT_START2 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x10, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x20, IP_ACTIVE_LOW, IPT_COIN2 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x40, IP_ACTIVE_LOW, IPT_COIN3 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(    0x80, 0x80, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 );
                PORT_DIPSETTING(    0x80, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                INPUT_PORTS_END();
        }};

        /* same as xevious, the only difference is DSW0 bit 7 */
        static InputPortPtr xeviousn_input_ports= new InputPortPtr(){ public void handler()  
        {
                PORT_START();	/* DSW0 */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 );
                PORT_DIPNAME( 0x02, 0x02, "Unknown 1", IP_KEY_NONE );
                PORT_DIPSETTING(    0x02, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                PORT_DIPNAME( 0x0c, 0x0c, "Right Coin", IP_KEY_NONE );
                PORT_DIPSETTING(    0x0c, "1 Coin/1 Credit" );
                PORT_DIPSETTING(    0x08, "1 Coin/2 Credit" );
                PORT_DIPSETTING(    0x04, "1 Coin/3 Credits" );
                PORT_DIPSETTING(    0x00, "1 Coin/6 Credits" );
                PORT_DIPNAME( 0x10, 0x10, "Unknown 2", IP_KEY_NONE );
                PORT_DIPSETTING(    0x10, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                PORT_DIPNAME( 0x60, 0x60, "Difficulty", IP_KEY_NONE );
                PORT_DIPSETTING(    0x40, "Easy" );
                PORT_DIPSETTING(    0x60, "Normal" );
                PORT_DIPSETTING(    0x20, "Hard" );
                PORT_DIPSETTING(    0x00, "Hardest" );
                PORT_DIPNAME( 0x80, 0x80, "Freeze?", IP_KEY_NONE );
                PORT_DIPSETTING(    0x80, "Off" );
                PORT_DIPSETTING(    0x00, "On" );

                PORT_START();	/* DSW1 */
                PORT_DIPNAME( 0x03, 0x03, "Left Coin", IP_KEY_NONE );
                PORT_DIPSETTING(    0x01, "2 Coins/1 Credit" );
                PORT_DIPSETTING(    0x03, "1 Coin/1 Credit" );
                PORT_DIPSETTING(    0x00, "2 Coins/3 Credits" );
                PORT_DIPSETTING(    0x02, "1 Coin/2 Credits" );
                /* TODO: bonus scores are different for 5 lives */
                PORT_DIPNAME( 0x1c, 0x1c, "Bonus Life", IP_KEY_NONE );
                PORT_DIPSETTING(    0x18, "10000 40000" );
                PORT_DIPSETTING(    0x14, "10000 50000" );
                PORT_DIPSETTING(    0x10, "20000 50000" );
                PORT_DIPSETTING(    0x0c, "20000 70000" );
                PORT_DIPSETTING(    0x08, "20000 80000" );
                PORT_DIPSETTING(    0x1c, "20000 60000" );
                PORT_DIPSETTING(    0x04, "20000 and 60000" );
                PORT_DIPSETTING(    0x00, "None" );
                PORT_DIPNAME( 0x60, 0x60, "Lives", IP_KEY_NONE );
                PORT_DIPSETTING(    0x40, "1" );
                PORT_DIPSETTING(    0x20, "2" );
                PORT_DIPSETTING(    0x60, "3" );
                PORT_DIPSETTING(    0x00, "5" );
                PORT_DIPNAME( 0x80, 0x80, "Cabinet", IP_KEY_NONE );
                PORT_DIPSETTING(    0x80, "Upright" );
                PORT_DIPSETTING(    0x00, "Cocktail" );

                PORT_START();	/* FAKE */
                /* The player inputs are not memory mapped, they are handled by an I/O chip. */
                /* These fake input ports are read by galaga_customio_data_r() */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY );
                PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY );
                PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY );
                PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY );
                PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED );	/* there's a BUTTON1 | IMPULSE here, */
                                                                                                        /* handled by galaga_customio_data_r() */
                PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 );
                PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED );

                PORT_START();	/* FAKE */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED );	/* there's a BUTTON1 | IMPULSE here, */
                                                                                                        /* handled by galaga_customio_data_r() */
                PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL );
                PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED );

                PORT_START();	/* FAKE */
                PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNUSED );
                PORT_BITX(0x04, IP_ACTIVE_LOW, IPT_START1 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x08, IP_ACTIVE_LOW, IPT_START2 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x10, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x20, IP_ACTIVE_LOW, IPT_COIN2 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x40, IP_ACTIVE_LOW, IPT_COIN3 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(    0x80, 0x80, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 );
                PORT_DIPSETTING(    0x80, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                INPUT_PORTS_END();
        }};

        /* same as xevious, the only difference is DSW0 bit 7. Note that the bit is */
        /* inverted wrt xeviousn. */
        static InputPortPtr sxevious_input_ports= new InputPortPtr(){ public void handler()  
        {
                PORT_START();	/* DSW0 */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 );
                PORT_DIPNAME( 0x02, 0x02, "Unknown 1", IP_KEY_NONE );
                PORT_DIPSETTING(    0x02, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                PORT_DIPNAME( 0x0c, 0x0c, "Right Coin", IP_KEY_NONE );
                PORT_DIPSETTING(    0x0c, "1 Coin/1 Credit" );
                PORT_DIPSETTING(    0x08, "1 Coin/2 Credit" );
                PORT_DIPSETTING(    0x04, "1 Coin/3 Credits" );
                PORT_DIPSETTING(    0x00, "1 Coin/6 Credits" );
                PORT_DIPNAME( 0x10, 0x10, "Unknown 2", IP_KEY_NONE );
                PORT_DIPSETTING(    0x10, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                PORT_DIPNAME( 0x60, 0x60, "Difficulty", IP_KEY_NONE );
                PORT_DIPSETTING(    0x40, "Easy" );
                PORT_DIPSETTING(    0x60, "Normal" );
                PORT_DIPSETTING(    0x20, "Hard" );
                PORT_DIPSETTING(    0x00, "Hardest" );
                PORT_DIPNAME( 0x80, 0x00, "Freeze?", IP_KEY_NONE );
                PORT_DIPSETTING(    0x00, "Off" );
                PORT_DIPSETTING(    0x80, "On" );

                PORT_START();	/* DSW1 */
                PORT_DIPNAME( 0x03, 0x03, "Left Coin", IP_KEY_NONE );
                PORT_DIPSETTING(    0x01, "2 Coins/1 Credit" );
                PORT_DIPSETTING(    0x03, "1 Coin/1 Credit" );
                PORT_DIPSETTING(    0x00, "2 Coins/3 Credits" );
                PORT_DIPSETTING(    0x02, "1 Coin/2 Credits" );
                /* TODO: bonus scores are different for 5 lives */
                PORT_DIPNAME( 0x1c, 0x1c, "Bonus Life", IP_KEY_NONE );
                PORT_DIPSETTING(    0x18, "10000 40000" );
                PORT_DIPSETTING(    0x14, "10000 50000" );
                PORT_DIPSETTING(    0x10, "20000 50000" );
                PORT_DIPSETTING(    0x0c, "20000 70000" );
                PORT_DIPSETTING(    0x08, "20000 80000" );
                PORT_DIPSETTING(    0x1c, "20000 60000" );
                PORT_DIPSETTING(    0x04, "20000 and 60000" );
                PORT_DIPSETTING(    0x00, "None" );
                PORT_DIPNAME( 0x60, 0x60, "Lives", IP_KEY_NONE );
                PORT_DIPSETTING(    0x40, "1" );
                PORT_DIPSETTING(    0x20, "2" );
                PORT_DIPSETTING(    0x60, "3" );
                PORT_DIPSETTING(    0x00, "5" );
                PORT_DIPNAME( 0x80, 0x80, "Cabinet", IP_KEY_NONE );
                PORT_DIPSETTING(    0x80, "Upright" );
                PORT_DIPSETTING(    0x00, "Cocktail" );

                PORT_START();	/* FAKE */
                /* The player inputs are not memory mapped, they are handled by an I/O chip. */
                /* These fake input ports are read by galaga_customio_data_r() */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY );
                PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY );
                PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY );
                PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY );
                PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED );	/* there's a BUTTON1 | IMPULSE here, */
                                                                                                        /* handled by galaga_customio_data_r() */
                PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 );
                PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED );

                PORT_START();	/* FAKE */
                PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY  | IPF_COCKTAIL);
                PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED );	/* there's a BUTTON1 | IMPULSE here, */
                                                                                                        /* handled by galaga_customio_data_r() */
                PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL );
                PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED );

                PORT_START();	/* FAKE */
                PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNUSED );
                PORT_BITX(0x04, IP_ACTIVE_LOW, IPT_START1 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x08, IP_ACTIVE_LOW, IPT_START2 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x10, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x20, IP_ACTIVE_LOW, IPT_COIN2 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(0x40, IP_ACTIVE_LOW, IPT_COIN3 | IPF_IMPULSE,
                                IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 );
                PORT_BITX(    0x80, 0x80, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 );
                PORT_DIPSETTING(    0x80, "Off" );
                PORT_DIPSETTING(    0x00, "On" );
                INPUT_PORTS_END();
        }};



        /* foreground characters */
        public static GfxLayout charlayout = new GfxLayout
	(
                8,8,	/* 8*8 characters */
                512,	/* 512 characters */
                1,	/* 1 bit per pixel */
                new int[]{ 0 },
                new int[]{ 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
                new int[]{ 0, 1, 2, 3, 4, 5, 6, 7 },
                8*8	/* every char takes 8 consecutive bytes */
        );
        /* background tiles */
        public static GfxLayout bgcharlayout = new GfxLayout
	(
                8,8,	/* 8*8 characters */
                512,	/* 512 characters */
                2,	/* 2 bits per pixel */
                new int[]{ 0, 512*8*8 },
                new int[]{ 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
                new int[]{ 0, 1, 2, 3, 4, 5, 6, 7 },
                8*8	/* every char takes 8 consecutive bytes */
        );
        /* sprite set #1 */
        public static GfxLayout spritelayout1 = new GfxLayout
	(
                16,16,	/* 16*16 sprites */
                128,	/* 128 sprites */
                3,	/* 3 bits per pixel */
               new int[] { 128*64*8+4, 0, 4 },
                new int[]{ 39*8, 38*8, 37*8, 36*8, 35*8, 34*8, 33*8, 32*8,
                        7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
                new int[]{ 0, 1, 2, 3, 8*8+0, 8*8+1, 8*8+2, 8*8+3,
                                16*8+0, 16*8+1, 16*8+2, 16*8+3, 24*8+0, 24*8+1, 24*8+2, 24*8+3 },
                64*8	/* every sprite takes 128 consecutive bytes */
        );
        /* sprite set #2 */
        public static GfxLayout spritelayout2 = new GfxLayout
	(
                16,16,	/* 16*16 sprites */
                128,	/* 128 sprites */
                3,	/* 3 bits per pixel */
                new int[] { 0, 128*64*8, 128*64*8+4 },
                new int[]{ 39*8, 38*8, 37*8, 36*8, 35*8, 34*8, 33*8, 32*8,
                        7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
                new int[]{ 0, 1, 2, 3, 8*8+0, 8*8+1, 8*8+2, 8*8+3,
                                16*8+0, 16*8+1, 16*8+2, 16*8+3, 24*8+0, 24*8+1, 24*8+2, 24*8+3 },
                64*8	/* every sprite takes 128 consecutive bytes */
        );
        /* sprite set #3 */
        public static GfxLayout spritelayout3 = new GfxLayout
	(
                16,16,	/* 16*16 sprites */
                64,	/* 64 sprites */
                3,	/* 3 bits per pixel (one is always 0) */
                new int[]{ 64*64*8, 0, 4 },
                new int[]{ 39*8, 38*8, 37*8, 36*8, 35*8, 34*8, 33*8, 32*8,
                        7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
                new int[]{ 0, 1, 2, 3, 8*8+0, 8*8+1, 8*8+2, 8*8+3,
                                16*8+0, 16*8+1, 16*8+2, 16*8+3, 24*8+0, 24*8+1, 24*8+2, 24*8+3 },
                64*8	/* every sprite takes 64 consecutive bytes */
        );



        static GfxDecodeInfo gfxdecodeinfo[] =
        {
                new GfxDecodeInfo( 1, 0x0000, charlayout, 128*4+64*8,  64 ),
                new GfxDecodeInfo( 1, 0x1000, bgcharlayout,        0, 128 ),
                new GfxDecodeInfo( 1, 0x3000, spritelayout1,   128*4,  64 ),
                new GfxDecodeInfo( 1, 0x5000, spritelayout2,   128*4,  64 ),
                new GfxDecodeInfo( 1, 0x9000, spritelayout3,   128*4,  64 ),
                new GfxDecodeInfo( -1 ) /* end of array */
        };



        static char color_prom[] =
        {
                /* 6A: palette red component */
                0xF0,0xF6,0xF3,0xF0,0xF5,0xFA,0xF2,0xF5,0xF9,0xFC,0xF4,0xF4,0xF9,0xF6,0xF5,0xF5,
                0xF7,0xF5,0xF5,0xF8,0xFD,0xFC,0xF7,0xF4,0xF2,0xF2,0xF2,0xF3,0xF5,0xF9,0xF7,0xF8,
                0xFA,0xF8,0xF7,0xF6,0xF7,0xF8,0xFF,0xF4,0xF3,0xF0,0xFD,0xF0,0xFA,0xF2,0xF0,0xFA,
                0xF2,0xF4,0xF5,0xFA,0xF8,0xF8,0xFF,0xFF,0xFF,0xF2,0xFE,0xFC,0xF0,0xFF,0xFE,0xF2,
                0xFC,0xFD,0xF0,0xF0,0xF4,0xF0,0xF0,0xF8,0xF6,0xF0,0xFC,0xF4,0xF5,0xF8,0xF7,0xF6,
                0xF2,0xF8,0xF2,0xF5,0xFB,0xFF,0xFC,0xF0,0xFA,0xF4,0xFE,0xFF,0xFF,0xFF,0xFC,0xFC,
                0xFF,0xFB,0xF7,0xF3,0xFF,0xF4,0xF4,0xF6,0xFA,0xFC,0xFA,0xF8,0xF0,0xF8,0xFF,0xF8,
                0xF4,0xF8,0xF4,0xF0,0xF0,0xF0,0xF0,0xF0,0xF4,0xF2,0xF8,0xF4,0xFF,0xFF,0xFF,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                /* 6D: palette green component */
                0xF0,0xF6,0xF8,0xFC,0xF2,0xFA,0xF7,0xF4,0xF9,0xFC,0xF8,0xF6,0xF9,0xF3,0xF5,0xF5,
                0xF8,0xF8,0xF8,0xF6,0xFB,0xF6,0xF4,0xF3,0xF2,0xF4,0xF6,0xF7,0xF9,0xF9,0xF8,0xF8,
                0xF8,0xF6,0xF6,0xF5,0xF7,0xF8,0xF0,0xF8,0xF7,0xF8,0xFB,0xF6,0xFB,0xF5,0xFC,0xF0,
                0xF4,0xF8,0xF5,0xFA,0xF8,0xF4,0xFF,0xFA,0xF6,0xF6,0xFA,0xF0,0xF0,0xFF,0xFE,0xF2,
                0xF6,0xFB,0xF5,0xF8,0xF4,0xFF,0xF8,0xF0,0xF0,0xF3,0xF4,0xF4,0xF5,0xF8,0xF7,0xF6,
                0xF2,0xF6,0xF5,0xF4,0xF7,0xF8,0xF4,0xFC,0xF6,0xF0,0xFE,0xFC,0xFC,0xFC,0xF8,0xFC,
                0xFF,0xFB,0xF7,0xF3,0xF8,0xF4,0xF4,0xF6,0xFA,0xFC,0xF8,0xF4,0xFF,0xF0,0xF0,0xF4,
                0xF2,0xF8,0xF4,0xF4,0xF8,0xF4,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xFF,0xFF,0xFA,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                /* 6E: palette blue component */
                0xF0,0xF6,0xFF,0xFC,0xF2,0xFA,0xFF,0xFF,0xF0,0xFC,0xF2,0xF0,0xF4,0xF2,0xF2,0xF5,
                0xF3,0xF3,0xF9,0xF0,0xF0,0xF0,0xF0,0xF2,0xF0,0xF0,0xF0,0xF1,0xFC,0xF7,0xF2,0xF2,
                0xF4,0xF2,0xF0,0xF0,0xF7,0xF8,0xF0,0xF7,0xFB,0xFC,0xF6,0xF8,0xFC,0xFA,0xF0,0xF0,
                0xF6,0xFB,0xF0,0xF0,0xF6,0xF4,0xF0,0xF0,0xF0,0xFA,0xF0,0xF0,0xFF,0xFF,0xFE,0xF2,
                0xF0,0xF0,0xF0,0xF0,0xF4,0xFF,0xFF,0xF0,0xF0,0xF0,0xF6,0xF6,0xF8,0xFA,0xF9,0xF8,
                0xF8,0xF2,0xFB,0xF0,0xF2,0xFF,0xF4,0xFF,0xF0,0xF0,0xF0,0xFA,0xF6,0xF4,0xF4,0xFC,
                0xF6,0xF4,0xF2,0xF3,0xF0,0xFC,0xF2,0xF4,0xF8,0xFA,0xF4,0xF2,0xF0,0xFF,0xFF,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF8,0xF4,0xF8,0xF4,0xF8,0xF4,0xF8,0xF4,0xFC,0xFA,0xF6,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
                /* 4Hlow/4Fhigh: background tiles lookup table */
                0x0A,0x0B,0x0D,0x0E,0x0C,0x09,0x06,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x0C,0x10,0x0B,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x1B,0x1A,0x0A,
                0x0A,0x28,0x09,0x06,0x00,0x00,0x00,0x00,0x0A,0x22,0x10,0x20,0x20,0x20,0x20,0x20,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x0A,0x18,0x19,0x1B,0x06,0x09,0x05,0x07,0x0A,0x00,0x05,0x19,0x06,0x12,0x0C,0x00,
                0x05,0x1D,0x0C,0x00,0x06,0x18,0x19,0x1B,0x00,0x3D,0x03,0x0F,0x19,0x19,0x1A,0x1B,
                0x0C,0x0A,0x1B,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x18,0x1B,0x0A,
                0x0C,0x1D,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x20,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x20,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,0x02,0x00,
                0x00,0x3D,0x02,0x3C,0x3C,0x3D,0x02,0x00,0x00,0x3D,0x03,0x0F,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x0F,0x0D,0x01,0x24,0x00,0x00,0x09,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x0A,0x00,0x24,0x18,0x06,0x1C,0x05,0x05,0x00,0x00,0x05,0x00,0x06,0x09,0x24,0x00,
                0x00,0x1D,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,0x03,0x00,
                0x00,0x3D,0x03,0x3C,0x3C,0x3D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                /* 3Llow/3Mhigh: sprite lookup table */
                /* These are probably not the original PROMs. The transparency information */
                /* (bit 7) is missing. The 0x80 bytes are mine, needed to fix the targeting cursor */
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x05,0x25,0x01,0x44,0x26,0x65,
                0x00,0x26,0x00,0x66,0x67,0x34,0x68,0x69,0x00,0x2F,0x00,0x66,0x67,0x34,0x68,0x69,
                0x00,0x47,0x00,0x66,0x67,0x34,0x68,0x69,0x00,0x48,0x00,0x66,0x67,0x34,0x68,0x69,
                0x00,0x00,0x00,0x66,0x67,0x34,0x68,0x69,0x00,0x3D,0x05,0x25,0x01,0x44,0x00,0x26,
                0x00,0x3D,0x05,0x25,0x01,0x44,0x00,0x2F,0x00,0x3D,0x05,0x25,0x01,0x44,0x00,0x47,
                0x00,0x3D,0x05,0x25,0x01,0x44,0x00,0x59,0x00,0x3D,0x05,0x25,0x01,0x44,0x00,0x00,
                0x00,0x05,0x01,0x3D,0x36,0x64,0x26,0x47,0x00,0x69,0x6A,0x6B,0x0D,0x59,0x00,0x26,
                0x00,0x26,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x26,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x2F,0x00,0x3D,0x00,0x00,0x00,0x00,
                0x00,0x47,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x3D,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x26,0x47,0x47,0x59,0x59,0x00,0x26,
                0x00,0x64,0x6F,0x6F,0x70,0x70,0x00,0x64,0x00,0x36,0x71,0x71,0x72,0x72,0x00,0x36,
                0x00,0x6C,0x43,0x43,0x73,0x73,0x00,0x6C,0x00,0x45,0x74,0x74,0x75,0x75,0x00,0x45,
                0x00,0x3C,0x76,0x76,0x77,0x77,0x00,0x3C,0x00,0x6D,0x78,0x78,0x79,0x79,0x00,0x6D,
                0x00,0x6E,0x7A,0x7A,0x7B,0x7B,0x00,0x6E,0x00,0x3D,0x00,0x66,0x67,0x34,0x68,0x69,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x09,0x46,0x09,0x00,0x00,0x00,0x00,0x00,0x09,0x80,0x09,0x00,0x00,0x00,0x00,
                0x00,0x64,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x3D,0x26,0x46,0x00,0x00,0x00,0x00,
                0x00,0x05,0x26,0x46,0x00,0x00,0x00,0x00,0x00,0x3D,0x26,0x00,0x00,0x00,0x00,0x00,
                0x00,0x26,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,0x46,0x00,0x00,0x00,0x00,0x00,
                0x00,0x46,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x46,0x26,0x00,0x00,0x00,0x00,
                0x00,0x09,0x80,0x26,0x00,0x00,0x00,0x00,0x00,0x05,0x01,0x63,0x00,0x00,0x00,0x00,
                0x00,0x25,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,0x09,0x05,0x25,0x01,0x44,0x69,
                0x00,0x3D,0x09,0x05,0x7C,0x7D,0x69,0x00,0x00,0x3D,0x7C,0x7D,0x5B,0x5C,0x7E,0x26,
                0x00,0x5D,0x26,0x2F,0x05,0x25,0x01,0x44,0x00,0x58,0x5C,0x2F,0x64,0x5E,0x01,0x00,
                0x00,0x2F,0x1F,0x60,0x7C,0x68,0x01,0x00,0x00,0x3D,0x2F,0x48,0x5F,0x05,0x25,0x01,
                0x00,0x2F,0x47,0x48,0x3D,0x5F,0x05,0x25,0x00,0x3D,0x5F,0x05,0x25,0x44,0x26,0x2F,
                0x00,0x5F,0x05,0x25,0x01,0x44,0x26,0x2F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
        };



        /* waveforms for the audio hardware */
        static char samples[] =
        {
                0x11,0x22,0x33,0x44,0x55,0x55,0x66,0x66,0x66,0x55,0x55,0x44,0x33,0x22,0x11,0xff,
                0xdd,0xcc,0xbb,0xaa,0x99,0x99,0x88,0x88,0x88,0x99,0x99,0xaa,0xbb,0xcc,0xdd,0xff,
                0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
                0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
                0xff,0x22,0x44,0x55,0x66,0x55,0x44,0x22,0xff,0xcc,0xaa,0x99,0x88,0x99,0xaa,0xcc,
                0xff,0x33,0x55,0x66,0x55,0x33,0xff,0xbb,0x99,0x88,0x99,0xbb,0xff,0x66,0xff,0x88,
                0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
                0x66,0x66,0x66,0x88,0x88,0x88,0x66,0x66,0x66,0x66,0x66,0x88,0x88,0x88,0x88,0x88,
                0x66,0x66,0x88,0x88,0x44,0x44,0x55,0xbb,0x66,0x66,0x44,0x44,0x44,0x44,0x55,0xff,
                0x99,0xaa,0xaa,0xaa,0xaa,0x88,0x88,0x33,0x99,0xaa,0xaa,0x66,0x66,0x88,0x88,0xff,
                0x66,0x44,0xff,0x22,0x44,0xff,0xdd,0x44,0x66,0x55,0x00,0x22,0x33,0xee,0xaa,0xff,
                0x44,0x00,0xbb,0xcc,0xee,0x99,0x88,0xbb,0x11,0xff,0xaa,0xcc,0xff,0xaa,0x88,0xff,
                0x44,0x66,0x66,0x66,0x66,0x44,0x33,0x11,0xff,0xee,0xdd,0xdd,0xdd,0xee,0x00,0x22,
                0x33,0x33,0x11,0xee,0xcc,0xaa,0xaa,0xaa,0xbb,0xdd,0xcc,0xbb,0xaa,0x99,0xbb,0xff,
                0x00,0x33,0x66,0x55,0xff,0x55,0x66,0x55,0x44,0x33,0xbb,0xaa,0x99,0x88,0x99,0xff,
                0x99,0x88,0xbb,0xee,0x00,0x66,0x55,0x44,0x66,0x00,0xbb,0x88,0xaa,0x99,0x88,0xee

        };



        public static MachineDriver machine_driver = new MachineDriver
	(
                /* basic machine hardware */
                new MachineCPU[] {
			new MachineCPU(
                                CPU_Z80,
                                3125000,	/* 3.125 Mhz (?) */
                                0,
                                readmem_cpu1,writemem_cpu1,null,null,
                                xevious_interrupt_1,100
                        ),
                        new MachineCPU(
                                CPU_Z80,
                                3125000,	/* 3.125 Mhz */
                                2,	/* memory region #2 */
                                readmem_cpu2,writemem_cpu2,null,null,
                                xevious_interrupt_2,1
                        ),
                        new MachineCPU(
                                CPU_Z80,
                                3125000,	/* 3.125 Mhz */
                                3,	/* memory region #3 */
                                readmem_cpu3,writemem_cpu3,null,null,
                                xevious_interrupt_3,2
                        )
                },
                60,
                xevious_init_machine,

                /* video hardware */
                28*8, 36*8, new rectangle( 0*8, 28*8-1, 0*8, 36*8-1 ),
                gfxdecodeinfo,
                256,128*4+64*8+64*2,
                xevious_vh_convert_color_prom,

                VIDEO_TYPE_RASTER,
                null,
                xevious_vh_start,
                xevious_vh_stop,
                xevious_vh_screenrefresh,

                /* sound hardware */
                samples,
                null,
                rallyx_sh_start,
                null,
                pengo_sh_update
        );



        /***************************************************************************

          Game driver(s)

        ***************************************************************************/

         static RomLoadPtr xevious_rom= new RomLoadPtr(){ public void handler()  
        {
                ROM_REGION(0x10000);	/* 64k for the first CPU */
                ROM_LOAD( "xvi_1.3p",     0x0000, 0x1000, 0x09964dda );
                ROM_LOAD( "xvi_2.3m",     0x1000, 0x1000, 0x60ecce84 );
                ROM_LOAD( "xvi_3.2m",     0x2000, 0x1000, 0x79754b7d );
                ROM_LOAD( "xvi_4.2l",     0x3000, 0x1000, 0xc7d4bbf0 );

                ROM_REGION(0xb000);	/* temporary space for graphics (disposed after conversion) */
                ROM_LOAD( "xvi_12.3b",    0x0000, 0x1000, 0x088c8b26 );	/* foreground characters */
                ROM_LOAD( "xvi_13.3c",    0x1000, 0x1000, 0xde60ba25 );	/* bg pattern B0 */
                ROM_LOAD( "xvi_14.3d",    0x2000, 0x1000, 0x535cdbbc );	/* bg pattern B1 */
                ROM_LOAD( "xvi_15.4m",    0x3000, 0x2000, 0xdc2c0ecb );	/* sprite set #1, planes 0/1 */
                ROM_LOAD( "xvi_18.4r",    0x5000, 0x2000, 0x02417d19 );	/* sprite set #1, plane 2, set #2, plane 0 */
                ROM_LOAD( "xvi_17.4p",    0x7000, 0x2000, 0xdfb587ce );	/* sprite set #2, planes 1/2 */
                ROM_LOAD( "xvi_16.4n",    0x9000, 0x1000, 0x605ca889 );	/* sprite set #3, planes 0/1 */
                /* 0xa000-0xafff empty space to decode sprite set #3 as 3 bits per pixel */
                
                ROM_REGION(0x10000);	/* 64k for the second CPU */
                ROM_LOAD( "xvi_5.3f",     0x0000, 0x1000, 0xc85b703f );
                ROM_LOAD( "xvi_6.3j",     0x1000, 0x1000, 0xe18cdaad );

                ROM_REGION(0x10000);	/* 64k for the audio CPU */
                ROM_LOAD( "xvi_7.2c",     0x0000, 0x1000, 0xdd35cf1c );

                ROM_REGION(0x4000);	/* gfx map */
                ROM_LOAD( "xvi_9.2a",     0x0000, 0x1000, 0x57ed9879 );
                ROM_LOAD( "xvi_10.2b",    0x1000, 0x2000, 0xae3ba9e5 );
                ROM_LOAD( "xvi_11.2c",    0x3000, 0x1000, 0x31e244dd );
                ROM_END();
        }};
        static RomLoadPtr xeviousa_rom= new RomLoadPtr(){ public void handler()  
        {
                ROM_REGION(0x10000);	/* 64k for the first CPU */
                ROM_LOAD( "xea-1m-a.bin", 0x0000, 0x2000, 0x8c2b50ec );
                ROM_LOAD( "xea-1l-a.bin", 0x2000, 0x2000, 0x0821642b );

                ROM_REGION(0xb000);	/* temporary space for graphics (disposed after conversion) */
                ROM_LOAD( "xvi_12.3b",    0x0000, 0x1000, 0x088c8b26 );	/* foreground characters */
                ROM_LOAD( "xvi_13.3c",    0x1000, 0x1000, 0xde60ba25 );	/* bg pattern B0 */
                ROM_LOAD( "xvi_14.3d",    0x2000, 0x1000, 0x535cdbbc );	/* bg pattern B1 */
                ROM_LOAD( "xvi_15.4m",    0x3000, 0x2000, 0xdc2c0ecb );	/* sprite set #1, planes 0/1 */
                ROM_LOAD( "xvi_18.4r",    0x5000, 0x2000, 0x02417d19 );	/* sprite set #1, plane 2, set #2, plane 0 */
                ROM_LOAD( "xvi_17.4p",    0x7000, 0x2000, 0xdfb587ce );	/* sprite set #2, planes 1/2 */
                ROM_LOAD( "xvi_16.4n",    0x9000, 0x1000, 0x605ca889 );	/* sprite set #3, planes 0/1 */
                /* 0xa000-0xafff empty space to decode sprite set #3 as 3 bits per pixel */
                        ROM_REGION(0x10000);	/* 64k for the second CPU */
                ROM_LOAD( "xea-4c-a.bin", 0x0000, 0x2000, 0x14d8fa03 );

                ROM_REGION(0x10000);	/* 64k for the audio CPU */
                ROM_LOAD( "xvi_7.2c",     0x0000, 0x1000, 0xdd35cf1c );

                ROM_REGION(0x4000);	/* gfx map */
                ROM_LOAD( "xvi_9.2a",     0x0000, 0x1000, 0x57ed9879 );
                ROM_LOAD( "xvi_10.2b",    0x1000, 0x2000, 0xae3ba9e5 );
                ROM_LOAD( "xvi_11.2c",    0x3000, 0x1000, 0x31e244dd );
                ROM_END();
        }};
        static RomLoadPtr sxevious_rom= new RomLoadPtr(){ public void handler()  
        {
                ROM_REGION(0x10000);	/* 64k for the first CPU */
                ROM_LOAD( "cpu_3p.rom",   0x0000, 0x1000, 0x1c8d27d5 );
                ROM_LOAD( "cpu_3m.rom",   0x1000, 0x1000, 0xfd04e615 );
                ROM_LOAD( "cpu_2m.rom",   0x2000, 0x1000, 0x294d5404 );
                ROM_LOAD( "cpu_2l.rom",   0x3000, 0x1000, 0x6a44bf92 );

                ROM_REGION(0xb000);	/* temporary space for graphics (disposed after conversion) */
                ROM_LOAD( "xvi_12.3b",    0x0000, 0x1000, 0x088c8b26 );	/* foreground characters */
                ROM_LOAD( "xvi_13.3c",    0x1000, 0x1000, 0xde60ba25 );	/* bg pattern B0 */
                ROM_LOAD( "xvi_14.3d",    0x2000, 0x1000, 0x535cdbbc );	/* bg pattern B1 */
                ROM_LOAD( "xvi_15.4m",    0x3000, 0x2000, 0xdc2c0ecb );	/* sprite set #1, planes 0/1 */
                ROM_LOAD( "xvi_18.4r",    0x5000, 0x2000, 0x02417d19 );	/* sprite set #1, plane 2, set #2, plane 0 */
                ROM_LOAD( "xvi_17.4p",    0x7000, 0x2000, 0xdfb587ce );	/* sprite set #2, planes 1/2 */
                ROM_LOAD( "xvi_16.4n",    0x9000, 0x1000, 0x605ca889 );	/* sprite set #3, planes 0/1 */
                /* 0xa000-0xafff empty space to decode sprite set #3 as 3 bits per pixel */
                
                ROM_REGION(0x10000);	/* 64k for the second CPU */
                ROM_LOAD( "cpu_3f.rom",   0x0000, 0x1000, 0xd4bd3d81 );
                ROM_LOAD( "cpu_3j.rom",   0x1000, 0x1000, 0xaf06be5f );

                ROM_REGION(0x10000);	/* 64k for the audio CPU */
                ROM_LOAD( "xvi_7.2c",     0x0000, 0x1000, 0xdd35cf1c );

                ROM_REGION(0x4000);	/* gfx map */
                ROM_LOAD( "xvi_9.2a",     0x0000, 0x1000, 0x57ed9879 );
                ROM_LOAD( "xvi_10.2b",    0x1000, 0x2000, 0xae3ba9e5 );
                ROM_LOAD( "xvi_11.2c",    0x3000, 0x1000, 0x31e244dd );
                ROM_END();
        }};



        static String xevious_sample_names[] =
        {
                "explo1.sam",	/* ground target explosion */
                "explo2.sam",	/* Solvalou explosion */
                null	/* end of array */
        };


        public static GameDriver xevious_driver = new GameDriver
        (
                "Xevious (Atari/Namco copyright)",
                "xevious",
                "Mirko Buffoni\nTatsuyuki Satoh\nNicola Salmoria",
                machine_driver,

                xevious_rom,
                null, null,
                xevious_sample_names,

                null/*TBR*/,xevious_input_ports,null/*TBR*/,null/*TBR*/,null/*TBR*/,

                color_prom, null, null,
                ORIENTATION_DEFAULT,

                /* to whomever will add high score support: remember that the table can hold 10 */
                /* letters. The Copyright dip switch selects 3 for Atari/Namco, 10 for Namco. */
                null, null
        );

        public static GameDriver xeviousa_driver = new GameDriver
        (
                "Xevious (Atari copyright)",
                "xeviousn",
                "Mirko Buffoni\nTatsuyuki Satoh\nNicola Salmoria",
                machine_driver,

                xeviousa_rom,
                null, null,
                xevious_sample_names,

                null/*TBR*/,xeviousn_input_ports,null/*TBR*/,null/*TBR*/,null/*TBR*/,

                color_prom, null, null,
                ORIENTATION_DEFAULT,

                null, null
        );

        public static GameDriver sxevious_driver = new GameDriver
        (
                "Super Xevious",
                "sxevious",
                "Mirko Buffoni\nTatsuyuki Satoh\nNicola Salmoria",
                machine_driver,

                sxevious_rom,
                null, null,
                xevious_sample_names,

                null/*TBR*/,sxevious_input_ports,null/*TBR*/,null/*TBR*/,null/*TBR*/,

                color_prom, null, null,
                ORIENTATION_DEFAULT,

                null, null
        );
    
}
